package org.dallasrowing.logbook.ui.view;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.dallasrowing.logbook.Config;
import org.dallasrowing.logbook.ui.util.MyContentProposalProvider;
import org.dallasrowing.logbook.ui.util.MyContentProposalProvider.ComboProposal;
import org.dallasrowing.logbook.util.FormatUtil;
import org.dallasrowing.model.Boat;
import org.dallasrowing.model.Rower;
import org.eclipse.jface.fieldassist.ComboContentAdapter;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.fieldassist.IContentProposal;
import org.eclipse.jface.fieldassist.IContentProposalListener;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class SWTNewEntryWindow implements NewEntryWindow{


	private Button submitNewEntryButton;
	private Text newEntryStartDate;
	private Combo boatCombo;
	private ComboModel<Boat> boatComboModel;
	private Shell newEntryDialog;
	private Group rowersGroup;
	private Combo[] rowers;
	private ComboModel<Rower>[] rowersModel;
	private Date startDate;
	private ContentProposalAdapter boatProposalAdapter;
	private Button cancelButton;
	private Button addMissingRower;

	public void openNewEntryWindow(Shell parent) {
		newEntryDialog = new Shell (parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL |SWT.RESIZE);
		newEntryDialog.setText ("Sign-In...");
		newEntryDialog.setLayout(new GridLayout(2, false));
		
		createNewEntryElements( newEntryDialog );
		newEntryDialog.setDefaultButton(submitNewEntryButton);
		
		validateEnableSubmit();
		
		newEntryDialog.setMinimumSize(400,100);
		
		newEntryDialog.pack();
		newEntryDialog.open(); 
	}

	private void createNewEntryElements( final Composite parent) {
		
		final Listener validateSubmitListener = new Listener() {
			public void handleEvent(Event event) {
				validateEnableSubmit();
			}
		};

		GridData gridData = new GridData( GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING  );
		Label l = new Label(parent, SWT.NONE);
		l.setText("Start Date:");
		l.setLayoutData( gridData );
		
		gridData = new GridData( GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING );
		newEntryStartDate = new Text(parent, SWT.BORDER);
		newEntryStartDate.setEnabled(false);
		newEntryStartDate.setLayoutData(gridData);
		
		gridData = new GridData( GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING  );
		l = new Label(parent, SWT.NONE);
		l.setText("Boat used:");
		l.setLayoutData( gridData );
		
		gridData = new GridData( GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING );
		boatCombo = new Combo(parent, SWT.DROP_DOWN );
		boatCombo.setLayoutData(gridData);
		boatComboModel = new ComboModel<Boat>();
		boatCombo.addListener(SWT.Selection, validateSubmitListener);
		
		gridData = new GridData( GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING );
		gridData.horizontalSpan = 2;
		rowersGroup = new Group ( parent, SWT.NONE );
		rowersGroup.setText("Rower(s)");
		rowersGroup.setLayoutData(gridData);
		rowersGroup.setLayout(new GridLayout(2,false));

		Composite buttonComposite = new Composite( parent, SWT.NONE);
		RowLayout rowLayout = new RowLayout();
		rowLayout.wrap = false;
		rowLayout.type = SWT.HORIZONTAL;
		buttonComposite.setLayout(rowLayout);
		
		submitNewEntryButton = new Button( buttonComposite, SWT.PUSH);
		submitNewEntryButton.setText("Submit");

		cancelButton = new Button( buttonComposite, SWT.PUSH);
		cancelButton.setText("Cancel");
		cancelButton.addListener(SWT.Selection, new Listener() {
		
			public void handleEvent(Event event) {
				parent.dispose();
			}
		
		});

		gridData = new GridData( GridData.HORIZONTAL_ALIGN_CENTER );
		addMissingRower = new Button( parent, SWT.PUSH);
		addMissingRower.setText("Person missing...");
		addMissingRower.setLayoutData(gridData);
		//OPTIONAL DUE TO MISUSE CONCERNS
		addMissingRower.setVisible(Config.rowerMissingEnabled());
		
	}

	protected void validateEnableSubmit() {
		boolean enabled = true;
		
		if (boatCombo.getSelectionIndex() == -1)
			enabled = false;
		
		for (int i =0; rowers != null && i < rowers.length && rowers[i] != null; i++)
		{
			if ( rowers[i].getSelectionIndex() == -1)
				enabled = false;
		}
		
		submitNewEntryButton.setEnabled(enabled);
	}

	public void setSubmitButtonListener(final Runnable action) {
		submitNewEntryButton.addListener(SWT.Selection, new Listener() {
		
			public void handleEvent(Event event) {
				action.run();
			}
		
		});		
	}
	
	public void setRowerMissingButtonListener(final Runnable action) {
		addMissingRower.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event event) {
				action.run();
			}
		});
	}

	public void setNewEntryStartDate(Date startDate) {
		this.startDate = startDate;
		newEntryStartDate.setText(FormatUtil.formatDate(startDate));
	}


	public void updateBoatsList(List<Boat> boats) {
		boatComboModel.load(boats);

		boatCombo.removeAll();
		for (Boat boat : boats)
		{
			boatCombo.add(boat.getName());
		}

		boatProposalAdapter = new ContentProposalAdapter( boatCombo, 
														  new ComboContentAdapter(),  
														  new MyContentProposalProvider(boatCombo.getItems()), 
														  null, 
														  MyContentProposalProvider.getAlphaNumericChars());
		boatProposalAdapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
	}

	public void setBoatSelectedListener(final Runnable runnable) {
		boatCombo.addSelectionListener(new SelectionListener() {
		
			public void widgetSelected(SelectionEvent arg0) {
				runnable.run();
			}
		
			public void widgetDefaultSelected(SelectionEvent arg0) {
				// TODO Auto-generated method stub
			}
		});
		
		boatProposalAdapter.addContentProposalListener(new IContentProposalListener() {
			
			public void proposalAccepted(IContentProposal proposal) {
				boatCombo.select( ((ComboProposal)proposal).getIndex());
				runnable.run();
			}
		
		});

	}

	public Boat getSelectedBoat() {
		int selectionIndex = boatCombo.getSelectionIndex();
		if (selectionIndex == -1)
			return null;
		return boatComboModel.getEntryFromIndex( selectionIndex);
	}

	@SuppressWarnings( "unchecked" )
	public void updateParticipantFields(int seats, boolean isWithCox, List<Rower> rowersData) {
		removeAllParticipantFields();
		
		rowers = new Combo[seats+1];
		rowersModel = new ComboModel[seats+1];
		for (int i=0; i< seats; i++)
		{
			createRowersLine(i, "Rower "+ (i+1) +":", rowersData);
		}
		if (isWithCox)
		{
			createRowersLine(seats, "Cox", rowersData);
		}

		validateEnableSubmit();
		redrawWindow();
	}

	private void redrawWindow() {
		this.rowersGroup.layout(true, true);
		newEntryDialog.layout(true, true);
		newEntryDialog.pack(true);
	}

	private void createRowersLine(int i, String title, List<Rower> rowersData) {
		GridData gridData = new GridData( GridData.HORIZONTAL_ALIGN_BEGINNING );
		Label label = new Label( rowersGroup, SWT.NONE);
		label.setLayoutData(gridData);
		label.setText(title);
		
		gridData = new GridData( GridData.HORIZONTAL_ALIGN_BEGINNING );
		rowers[i] = new Combo( rowersGroup, SWT.DROP_DOWN);
		rowersModel[i] = new ComboModel<Rower>();
		rowersModel[i].load(rowersData);
		label.setLayoutData(gridData);

		rowers[i].addListener(SWT.Modify, new Listener() {
			public void handleEvent(Event event) {
				validateEnableSubmit();
			}
		});
		
		for (Rower rower : rowersData)
		{
			rowers[i].add(rower.getName());
		}
		
		final Combo currentCombo = rowers[i];
		ContentProposalAdapter adapter = new ContentProposalAdapter( currentCombo, 
				  new ComboContentAdapter(),  
				  new MyContentProposalProvider(currentCombo.getItems()), 
				  null, 
				  MyContentProposalProvider.getAlphaNumericChars());
		adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
		adapter.addContentProposalListener(new IContentProposalListener() {
		
			public void proposalAccepted(IContentProposal arg0) {
				ComboProposal proposal = (ComboProposal) arg0;
				currentCombo.select(proposal.getIndex());
				validateEnableSubmit();
			}
		
		});
	}

	private void removeAllParticipantFields() {
		for (Control child : rowersGroup.getChildren() )
		{
			child.dispose();
		}
	}

	public List<Rower> getSelectedRowers() {
		List<Rower> selectedRowers = new ArrayList<Rower>();
		for ( int i=0; i< rowers.length; i++)
		{
			if (rowers[i] != null && rowers[i].getSelectionIndex() != -1)
			{
				selectedRowers.add(rowersModel[i].getEntryFromIndex( rowers[i].getSelectionIndex()));
			}
		}
		return selectedRowers;
	}

	public void closeWindow() {
		newEntryDialog.dispose();
	}

	public String getTypedBoatName() {
		return boatCombo.getText();
	}

	public Date getStartDate() {
		return startDate;
	}

	public NewRowerWindow openNewRowerWindow() {
		SWTNewRowerWindow newRowerWindow = new SWTNewRowerWindow();
		newRowerWindow.createNewRowerWindow(this.newEntryDialog);
		return newRowerWindow;
	}
}


